package com.gitee.wsl.compose.chart.xy.axis

import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import com.gitee.wsl.common.ui.base.ColorOrBrush
import com.gitee.wsl.common.ui.base.toColorOrBrush
import com.gitee.wsl.common.ui.draw.CollageElements
import com.gitee.wsl.common.ui.draw.CollageGroup
import com.gitee.wsl.common.ui.theme.local.Web
import com.gitee.wsl.common.ui.draw.type.Orient
import com.gitee.wsl.mathematics.function.scale.FirstLastRange

@Composable
fun <D> Axis(
    orient: Orient,
    scale: FirstLastRange<D, Float>,
    tickValues: List<D> = listOf(),
    tickSizeInner: Float = 6.0f,
    tickSizeOuter: Float = 6.0f,
    tickPadding: Float = 3.0f,
    axisStroke: ColorOrBrush? = Color.Web.black.toColorOrBrush(),
    axisStrokeWidth: Float? = 1.0f,
    tickStroke: ColorOrBrush? = Color.Web.black.toColorOrBrush(),
    tickStrokeWidth: Float? = 1.0f,
    fontSize: Float = 12.0f,
    fontColor: ColorOrBrush? = Color.Web.black.toColorOrBrush(),
    fontFamily: FontFamily = FontFamily.SansSerif,
    fontWeight: FontWeight = FontWeight.Normal,
    fontStyle: FontStyle = FontStyle.Normal,
    tickFormat: (D) -> String = { n: D -> n.toString() }
) {
    val axisElement = axisElement(orient, scale) {
        this.tickValues = tickValues
        this.tickSizeInner = tickSizeInner
        this.tickSizeOuter = tickSizeOuter
        this.tickPadding = tickPadding
        this.axisStroke = axisStroke
        this.axisStrokeWidth = axisStrokeWidth
        this.tickStroke = tickStroke
        this.tickStrokeWidth = tickStrokeWidth
        this.fontSize = fontSize
        this.fontColor = fontColor
        this.fontFamily = fontFamily
        this.fontWeight = fontWeight
        this.fontStyle = fontStyle
        this.tickFormat = tickFormat
    }
    val annotations = axisElement.toAxisAnnotations()
    val lines = axisElement.toAxisLine()
    if (lines != null) {
        CollageElements(
            nodes = listOf(lines)
        )
    }
    val isHorizontal = axisElement.orient.isHorizontal()
    annotations.forEach { (data, tick, text) ->
        val translation = axisElement.position(data).toFloat()
        CollageGroup(
            translationX = if (isHorizontal) translation.dp else 0.dp,
            translationY = if (!isHorizontal) translation.dp else 0.dp
        ) {
            CollageElements(listOfNotNull(tick, text))
        }
    }
}

private fun <D> axisElement(
    orient: Orient,
    scale: FirstLastRange<D, Float>,
    init: AxisElement<D>.() -> Unit = {}
): AxisElement<D> = AxisElement(orient, scale).apply { init(this) }





